package com.zhangwoo.analyser.jobs.matcher;

import java.io.StringReader;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.log4j.Logger;

import com.google.gson.Gson;
import com.google.gson.stream.JsonReader;
import com.zhangwoo.analyser.jobs.po.MainComments;
import com.zhangwoo.analyser.jobs.po.SubComments;
import com.zhangwoo.util.Alarm;
import com.zhangwoo.util.JavaUtil;

@SuppressWarnings({ "rawtypes", "unchecked" })
public class TextMatcherTester {

	private Logger logger = Logger.getLogger(getClass());

	/**
	 * 针对文本内容进行匹配过程
	 * 
	 * @param strategy
	 *            策略
	 * @param text
	 *            文本内容（单条评价）
	 * @return
	 */
	public void processText(String strategy, String goodTerms, String badTerms,
			String otherTerms, String text) {
		try {

			text = text.replace(",[{", ",\"scoms\":[{")
					.replace("\",{", "\",\"scoms\":[{").replace("\n", "")
					.replace("\t", "").replace("\r", "").replace("/r", "")
					.replace("/n", "");
			logger.debug("text : " + text);

			// 1.策略放在全局变量中
			if (strategy == null || strategy.trim().length() == 0
					|| text == null || text.trim().length() == 0)
				return; // 若没有任何策略内容则返回。
			logger.debug("strategy " + strategy);

			// 好中差全匹配的词预先提取出来
			String tempGoodAll = goodTerms
					.replaceAll("#\\d+\\+[^~]+~[^#]+", "").replace("~", "");
			String tempBadAll = badTerms.replaceAll("#\\d+\\+[^~]+~[^#]+", "")
					.replace("~", "");
			String tempOtherAll = otherTerms.replaceAll("#\\d+\\+[^~]+~[^#]+",
					"").replace("~", "");

			// 2.所有关键词表达式对title进行 直接匹配
			Gson gson = new Gson();
			JsonReader reader = new JsonReader(new StringReader(text));
			reader.setLenient(true);

			MainComments ms = gson.fromJson(reader, MainComments.class);
			// MainComments ms = new Gson().fromJson(text, MainComments.class);
			List<String> exps = new ArrayList<String>();
			Collections.addAll(exps, strategy.split("#"));

			String mid = null;

			for (String exp : exps) { // 每项策略
				if (exp.trim().length() == 0)
					continue;

				if (Alarm.isAlerm(("#" + exp).replaceAll("#[^~]+~", ""),
						(ms.getTitle()))) { // 是否命中单个表达式
					// 若title命中策略 (1)所有的评论匹配好差存入词频库 (2)所有的评论插入match库

					logger.debug("term : '" + exp + "' match title : '"
							+ ms.getTitle() + "'");

					String expid = exp.split("~")[0].split("\\+")[0];
					String expclass = exp.split("~")[0].split("\\+")[1]; // 关键词匹配的类别

					List<Object[]> parasValuesWordFre = new ArrayList<Object[]>();
					List<Object[]> parasValuesMatch = new ArrayList<Object[]>();
					for (SubComments sc : ms.getScoms()) {
						List<Object[]> parasValuesWordFre_tmp = new ArrayList<Object[]>();
						mid = md5s(sc.getRateContent() + sc.getRateDate());
						// 评价的唯一标识 mid，使用评价内容+时间

						// (1)

						// 使用class_name过滤评价关键词
						StringBuffer tempGood = new StringBuffer(tempGoodAll);
						StringBuffer tempBad = new StringBuffer(tempBadAll);
						StringBuffer tempOther = new StringBuffer(tempOtherAll);

						long t1 = System.currentTimeMillis();

						List<String[]> tempTerms = new ArrayList<String[]>();
						tempTerms = JavaUtil.matchAll(goodTerms, "#([^~]+,)*"
								+ expclass + "(,[^~]+)*~([^#]+)");
						for (String[] matchs : tempTerms) {
							tempGood.append("#");
							tempGood.append(matchs[3]);
						}
						tempTerms = JavaUtil.matchAll(badTerms, "#([^~]+,)*"
								+ expclass + "(,[^~]+)*~([^#]+)");
						for (String[] matchs : tempTerms) {
							tempBad.append("#");
							tempBad.append(matchs[3]);
						}
						tempTerms = JavaUtil.matchAll(otherTerms, "#([^~]+,)*"
								+ expclass + "(,[^~]+)*~([^#]+)");
						for (String[] matchs : tempTerms) {
							tempOther.append("#");
							tempOther.append(matchs[3]);
						}

						long t2 = System.currentTimeMillis();
						logger.debug("tempTerms done need : " + (t2 - t1));

						Set termsGoodMatch = null;
						Set termsBadMatch = null;
						try {
							termsGoodMatch = removeShortTerm(allACMatch(
									tempGood.toString().split("#"),
									sc.getRateContent() + sc.getAppendComment()
											+ sc.getContentTitle()));
							termsBadMatch = removeShortTerm(allACMatch(tempBad
									.toString().split("#"),
									sc.getRateContent() + sc.getAppendComment()
											+ sc.getContentTitle()));
							Set termsOtherMatch = removeShortTerm(allACMatch(
									tempOther.toString().split("#"),
									sc.getRateContent() + sc.getAppendComment()
											+ sc.getContentTitle()));
							for (Object t : termsGoodMatch)
								parasValuesWordFre_tmp.add(new Object[] { mid,
										t, 1, sc.getRateDate() });
							for (Object t : termsBadMatch)
								parasValuesWordFre_tmp.add(new Object[] { mid,
										t, 0, sc.getRateDate() });
							for (Object t : termsOtherMatch)
								parasValuesWordFre_tmp.add(new Object[] { mid,
										t, 2, sc.getRateDate() });

							parasValuesWordFre_tmp = removeWordFre(parasValuesWordFre_tmp);
						} catch (Exception e) {
							Logger.getLogger(TextMatcherTester.class).error(
									"match Word Fre error ! ", e);
						}
						parasValuesWordFre.addAll(parasValuesWordFre_tmp);

						long t3 = System.currentTimeMillis();
						logger.debug("parasValuesWordFre done need : "
								+ (t3 - t2));
						// (2)
						try {
							parasValuesMatch
									.add(new Object[] {
											mid,
											heightLight(
													removeSep(
															("#" + exp)
																	.replaceAll(
																			"#[^~]+~",
																			""))
															.split("\\~\\$\\~"),
													ms.getTitle()),// 标题
											ms.getDomian(),// 域名
											ms.getUrl(),// 地址
											dateToString(stringToDate(ms.getTime())),// 添加时间
//											ms.getTime(),// 添加时间
											sc.getDisplayUserNick(),// 评论人昵称
											heightLight(parasValuesWordFre_tmp,
													sc.getRateContent()),// 评论内容
											sc.getRateDate(),// 评论时间
											heightLight(parasValuesWordFre_tmp,
													sc.getAppendComment()),// 追加评价
											sc.getCons(),// 不足评论内容
											sc.getPros(),// 使用心得
											heightLight(parasValuesWordFre_tmp,
													sc.getContentTitle()),// 评论内容总结标题
											sc.getStarNum(),// 评论星数
											expid,// 关键词ID
											(termsGoodMatch.size() == 0 && termsBadMatch
													.size() == 0) ? 2
													: (termsGoodMatch.size() >= termsBadMatch
															.size() ? 1 : 0) // 维度标志
									// 1好
									// 0差
									// 2其他
									});
						} catch (Exception e) {
							Logger.getLogger(TextMatcherTester.class).error(
									"match Word error ! ", e);
						}
						long t4 = System.currentTimeMillis();
						logger.debug("parasValuesMatch done need : " + (t4 - t3));

					}
					logger.debug("params done!!! ");
				}
			}
		} catch (Exception e) {
			Logger.getLogger(TextMatcherTester.class).error(
					"processText json error ! ", e);
		}

		logger.debug("job done!!! ");
	}

	public static void main(String[] args) {
//		String path="//hadoop//hadoop-1.0.3//";
		String path="E:\\xx\\";
		String[] all = JavaUtil.readFile(path+"20130404.txt").split("\n");
		String strategy = JavaUtil.readFile(path+"strategy.txt");
		String goodTerms = JavaUtil.readFile(path+"good.txt");
		String badTerms = JavaUtil.readFile(path+"bad.txt");
		String otherTerms = JavaUtil.readFile(path+"other.txt");
		System.out.println("process begin  : " +new java.util.Date());
		long t1=System.currentTimeMillis();
		for(String a: all){
			new TextMatcherTester().processText(strategy, goodTerms, badTerms, otherTerms, a);
		}
		long t2 = System.currentTimeMillis();
		System.out.println("process end  : " +new java.util.Date());
		System.out.println("process done need : " + (t2 - t1));
	}

	/**
	 * 字符串转换为java.util.Date<br>
	 * 支持格式为 yyyy.MM.dd G 'at' hh:mm:ss z 如 '2002-1-1 AD at 22:10:59 PSD'<br>
	 * yy/MM/dd HH:mm:ss 如 '2002/1/1 17:55:00'<br>
	 * yy/MM/dd HH:mm:ss pm 如 '2002/1/1 17:55:00 pm'<br>
	 * yy-MM-dd HH:mm:ss 如 '2002-1-1 17:55:00' <br>
	 * yy-MM-dd HH:mm:ss am 如 '2002-1-1 17:55:00 am' <br>
	 * 
	 * @param time
	 *            String 字符串<br>
	 * @return Date 日期<br>
	 */
	public static Date stringToDate(String time) {
		SimpleDateFormat formatter;
		int tempPos = time.indexOf("AD");
		time = time.trim();
		formatter = new SimpleDateFormat("yyyy.MM.dd G 'at' hh:mm:ss z");
		if (tempPos > -1) {
			time = time.substring(0, tempPos) + "公元"
					+ time.substring(tempPos + "AD".length());// china
			formatter = new SimpleDateFormat("yyyy.MM.dd G 'at' hh:mm:ss z");
		}
		tempPos = time.indexOf("-");
		if (tempPos > -1 && (time.indexOf(" ") < 0)) {
			formatter = new SimpleDateFormat("yyyyMMddHHmmssZ");
		} else if (time.matches("\\d{14}")) {
			formatter = new SimpleDateFormat("yyyyMMddHHmmss");
		} else if ((time.indexOf("/") > -1) && (time.indexOf(" ") > -1)) {
			formatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
		} else if ((time.indexOf("-") > -1) && (time.indexOf(" ") > -1)) {
			formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		} else if ((time.indexOf("/") > -1) && (time.indexOf("am") > -1)
				|| (time.indexOf("pm") > -1)) {
			formatter = new SimpleDateFormat("yyyy-MM-dd KK:mm:ss a");
		} else if ((time.indexOf("-") > -1) && (time.indexOf("am") > -1)
				|| (time.indexOf("pm") > -1)) {
			formatter = new SimpleDateFormat("yyyy-MM-dd KK:mm:ss a");
		}
		ParsePosition pos = new ParsePosition(0);
		java.util.Date ctime = formatter.parse(time, pos);

		return ctime;
	}
	public static String dateToString(Date time){ 
	    SimpleDateFormat formatter; 
	    formatter = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss"); 
	    String ctime = formatter.format(time); 

	    return ctime; 
	} 

	private Set allACMatch(String[] terms, String text) {

		Set termsThatHit = new HashSet();
		for (String term : terms) {
			if (text.indexOf(term) != -1)
				termsThatHit.add(term);
		}

		return termsThatHit;
	}

	private String heightLight(List<Object[]> parasValuesWordFres,
			String origStr) {
		if (origStr == null || origStr.trim().length() == 0)
			return origStr;
		// 好：#04D215 差：#FF0F00 其他：#FF9E01
		String color = "#FF9E01";
		for (Object[] parasValuesWordFre : parasValuesWordFres) {
			if (parasValuesWordFre[1].toString() != null
					&& String.valueOf(parasValuesWordFre[1].toString()).trim()
							.length() > 0) {
				if (parasValuesWordFre[2].toString().equals("1")) {
					color = "#04D215";
				} else if (parasValuesWordFre[2].toString().equals("0")) {
					color = "#FF0F00";
				} else if (parasValuesWordFre[2].toString().equals("2")) {
					color = "#FF9E01";
				}

				origStr = origStr.replace(
						String.valueOf(parasValuesWordFre[1].toString()),
						"<font color=\"" + color + "\">"
								+ parasValuesWordFre[1].toString() + "</font>");
			}
		}
		return origStr;
	}

	private String heightLight(Object[] objects, String origStr) {
		if (origStr == null || origStr.trim().length() == 0)
			return origStr;

		for (Object key : objects) {
			if (key != null && String.valueOf(key).trim().length() > 0)
				origStr = origStr.replace(String.valueOf(key),
						"<font color=\"#0000FF\">" + key + "</font>");
		}
		return origStr;
	}

	private String removeSep(String orgStr) {
		return orgStr.replaceAll("#[^~]+~", "\\~\\$\\~")
				.replaceAll("\\s+", " ").replace(" and ", "~$~")
				.replace(" or ", "~$~").replace(" not ", "~$~")
				.replace("#", "~$~").replace("(", "~$~").replace(")", "~$~")
				.replace(",", "~$~");
	}

	private List<Object[]> removeWordFre(List<Object[]> parasValuesWordFre_tmp) {
		List<Object[]> parasValuesWordFre_res = new ArrayList<Object[]>();

		StringBuffer allMatchStr = new StringBuffer();

		for (Object[] term : parasValuesWordFre_tmp) {
			allMatchStr.append(term[1].toString());
			allMatchStr.append(";");
		}

		for (Object[] term : parasValuesWordFre_tmp) {
			if (JavaUtil.matchAll(allMatchStr.toString(), term[1].toString())
					.size() == 1) {
				parasValuesWordFre_res.add(term);
			}
		}
		return parasValuesWordFre_res;
	}

	private Set removeShortTerm(Set originTerm) {
		Set termsAllMatchResult = new HashSet();

		StringBuffer allMatchStr = new StringBuffer();

		for (Object term : originTerm) {
			allMatchStr.append(term.toString());
			allMatchStr.append(";");
		}

		for (Object term : originTerm) {
			if (JavaUtil.matchAll(allMatchStr.toString(), term.toString())
					.size() == 1) {
				termsAllMatchResult.add(term);
			}
		}

		return termsAllMatchResult;
	}

	public String md5s(String plainText) {
		try {
			MessageDigest md = MessageDigest.getInstance("MD5");
			md.update(plainText.getBytes());
			byte b[] = md.digest();

			int i;

			StringBuffer buf = new StringBuffer("");
			for (int offset = 0; offset < b.length; offset++) {
				i = b[offset];
				if (i < 0)
					i += 256;
				if (i < 16)
					buf.append("0");
				buf.append(Integer.toHexString(i));
			}
			return buf.toString();
		} catch (NoSuchAlgorithmException e) {
			Logger.getLogger(TextMatcherTester.class)
					.error("md5 error ! ", e);

		}
		return null;
	}

}
